Developer Documentation

QuickTime 4 API Documentation

3D Graphics Programming with QuickDraw 3D 1.5.4

Previous | QD3D Book | Overview | Chapter Contents | Next |

Reference Counts

As mentioned in "QuickDraw 3D Object Subclasses" , a shared object is a QuickDraw 3D object that can be shared by two or more other QuickDraw 3D objects. QuickDraw 3D maintains an internal reference count for each shared object to keep track of the number of times an object is being shared. Certain operations on the object increase the reference count, and other operations decrease it. For example, when you first create a spot light (by calling Q3SpotLight_New ), its reference count is set to 1. If you later share that light (for example, by adding it to a group object), the reference count of the light is increased to indicate the additional link to the light. Figure 6 illustrates a series of operations involving a spot light and a group.

In step 1, an application creates a new spot light by calling Q3SpotLight_New . As indicated above, the reference count of the new spot light is set to 1. Then, in step 2, the application creates a new light group. A light group is a shared object and hence also has a reference count, which is set to 1 upon its creation. In step 3, the application adds the spot light to the light group by calling Q3Group_AddObject . The reference count of the spot light is therefore increased to 2, because both the application and the light group possess references to the spot light. Note that the reference count of the group remains at 1.

In general, when you create a light and add it to a group, you can dispose of your application's reference to the light by calling Q3Object_Dispose . When this is done, in step 4, the reference count of the light is decremented to 1. The only remaining reference to the light is maintained by the group, not by the application. Finally, when you have finished using the light, you can dispose of the group object by calling Q3Object_Dispose once again (step 5). When that happens, the objects in the group are disposed of and the group itself is disposed of. The reference counts of both the light and the group fall to 0, in which case they are both removed from memory.

If the application had not explicitly disposed of the spot light (as happened in step 4), the reference count of the light would have remained at 2 until the group was disposed of (step 5), at which time it would have decreased to 1. The application could then call Q3Object_Dispose to decrease the reference count to 0, thereby disposing of the light object. In effect, _New and _Dispose calls define the scope of an object inside your application. You cannot operate on the object until you've created it using a _New call, and you cannot in general operate on an object after you've disposed of it by calling Q3Object_Dispose .

Figure 6 Incrementing and decrementing reference counts

Certain operations increase the reference counts of shared objects, including

Naturally, the inverse operations decrease the reference counts of shared objects, including

For example, the following code gets and disposes of the camera object associated with a view:

TQ3ViewObject       view;
TQ3CameraObject     camera;
Q3View_GetCamera(view, &camera);
Q3Object_Dispose(camera);
camera = NULL;

The following code shows how a reference count is increased when obtaining an object at a given position in a group. Note that the transform which Q3Group_GetPositionObject returned from the group must be disposed of:

TQ3GroupObject          group;
TQ3GroupPosition        position;
TQ3TransformObject      transform;
TQ3Matrix4x4            matrix;
Q3Group_GetPositionObject(group, position, &transform);
Q3Transform_GetMatrix(transform, &matrix);
Q3Object_Dispose(transform);
transform = NULL;

If you do not directly or indirectly balance every operation that increments an object's reference count with an operation that decrements the reference count, you risk creating memory leaks. See the Listing 1-6 for examples of how to balance an object's reference count.

You need to directly dispose only of an object reference that your application receives when it creates a QuickDraw 3D object. Any other reference to the object must be indirectly disposed of. For example, suppose that you create a translate transform object and then add it to a group twice, as follows:

myTransform = Q3TranslateTransform_New(&myVector3D);
Q3Group_AddObject(myGroup, myTransform);
Q3Group_AddObject(myGroup, myTransform);

In this example, the reference count is incremented each time you call Q3Group_AddObject . However, you should dispose of the transform object only once, because the transform's reference count is decremented twice when you dispose of the group.


© 1997 Apple Computer, Inc.

Previous | QD3D Book | Overview | Chapter Contents | Next |